<script lang="ts" setup>
import { ref, provide, useSlots, onMounted, onBeforeUnmount, computed } from 'vue'
import { buildStyles } from '../utils'

interface Props {
    indicatorOffset?: {
        bottom?: number
    },
    swipeThreshold?: number
}

const currentIndex = ref(0)
const slots = useSlots()
const carouselRef = ref<HTMLElement | null>(null)
const content = ref<HTMLElement | null>(null)

provide('currentIndex', currentIndex)

const props = withDefaults(defineProps<Props>(), {
    indicatorOffset: () => ({ bottom: 10 })
})

const styles: any = buildStyles(() => {
    return {
        bottom: props.indicatorOffset.bottom + "px"
    }
})

const swipeThreshold = computed(() => props.swipeThreshold ?? 30)

let startX = 0, moveX = 0, isSwiping = false, touchStartTime = 0

const handleTouchStart = (e: TouchEvent) => {
    startX = e.touches[0].clientX
    isSwiping = true
    touchStartTime = Date.now()
}

const handleTouchMove = (e: TouchEvent) => {
    if (!isSwiping || !content.value) return
    moveX = e.touches[0].clientX
    const diffX = moveX - startX

    // Use translate3d for GPU acceleration
    content.value.style.transform = `translate3d(${diffX}px, 0, 0)`
}

const handleTouchEnd = () => {
    if (!isSwiping || !content.value) return
    isSwiping = false

    const diffX = moveX - startX
    const velocity = Math.abs(diffX) / (Date.now() - touchStartTime)

    content.value.style.transition = 'transform 0.3s ease'

    if (Math.abs(diffX) > swipeThreshold.value || velocity > 0.3) {
        if (diffX > 0) {
            currentIndex.value = Math.max(currentIndex.value - 1, 0)
        } else {
            currentIndex.value = Math.min(
                currentIndex.value + 1,
                (slots.default?.().length ?? 1) - 1
            )
        }
        content.value.style.transform = 'translate3d(0, 0, 0)'
    } else {
        // Bounce back if not swiped enough
        content.value.style.transform = 'translate3d(0, 0, 0)'
    }
}

onMounted(() => {
    if (carouselRef.value) {
        const container: any = carouselRef.value
        content.value = carouselRef.value.querySelector('.umrp-carousel-wrapper')
        container.addEventListener('touchstart', handleTouchStart)
        container.addEventListener('touchmove', handleTouchMove)
        container.addEventListener('touchend', handleTouchEnd)
    }
})

onBeforeUnmount(() => {
    if (carouselRef.value) {
        const container = carouselRef.value

        container.removeEventListener('touchstart', handleTouchStart)
        container.removeEventListener('touchmove', handleTouchMove)
        container.removeEventListener('touchend', handleTouchEnd)
    }
})
</script>

<template>
    <div class="umrp-carousel" ref="carouselRef">
        <div class="umrp-carousel-wrapper">
            <template :key="key" v-for="(item, key) in slots.default?.()">
                <component :is="item" :index="key"></component>
            </template>
        </div>
        <div class="indicator" :style="styles">
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>
</template>

<style lang="scss" scoped>
.umrp-carousel {
    position: relative;
    overflow: hidden;
}

.indicator {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);

    div {
        width: 8px;
        height: 8px;
        display: inline-block;
        cursor: pointer;
        margin: 0 5px;
        background-color: #666;
        border-radius: 50%;
    }
}
</style>